#pragma once
#include <map>
#include "../Structure/unit.h"

#ifdef GRAPHENETOOLS_EXPORTS
#ifndef GRAPHENETOOLS_DLL_API
#define GRAPHENETOOLS_DLL_API __declspec(dllexport)
#endif
#else
#ifndef GRAPHENETOOLS_DLL_API
#define GRAPHENETOOLS_DLL_API __declspec(dllimport)
#endif
#endif

class GRAPHENETOOLS_DLL_API System
{
	std::map<size_t, Unit *> units; // This holds all objects and maps them to an integer ID.
	size_t CurrentID; // This holds the next available ID.

public:
	// This default constructor will initiate an empty system with no magnetic field.
	System();
	// This default destructor will deallocate all objects it owns.
	~System();
	
	static System Std; // This holds a standard system that is always available.
	
	// This getter function will fetch the object corresponding to the ID. If the ID does not point to an object a null pointer is returned.
	int getId(Unit *obj) const;
	// This getter function will fetch the object corresponding to the ID. If the ID does not point to an object a null pointer is returned.
	Unit *getUnit(int id) const;
	
	// This convenience setter function will initialize all objects registered in this system.
	void initializeAllObjects();

	// This function will register the object and return an ID. This object is now own by the system and it will take care of deallocating.
	size_t registerObject(Unit *unit);
	// This function will release the object corresponding to the ID. This object is now disowned by the system and it will not deallocate it.
	void releaseObject(int id);
	// This function will release and deallocate the object corresponding to the ID.
	void eraseObject(int id);
	// This function will release all objects. The objects are now disowned by the system and it will not deallocate them.
	void releaseAllObjects();
	// This function will release and deallocate all objects.
	void eraseAllObjects();
	
	// System Variables:
	double epsilon,Delta,gamma0,gamma1,gamma2,gamma3,gamma4; //Energies for onsite and hopping elements.
};

